'''
= Function Memoization =

This module contains the memoized function decorator, which will cache the
result of functions to speed them up.
'''

from functools import wraps


def memoized(f):
    '''Function decorator without arguments. Caches the result of the decorated
    function based on the arguments provided.
    
    Note that a normal dictionary is used, which will prolong the durations of
    all objects involved in a function call. The dictionary is stored in the
    function and will be deleted if the function is.'''
    
    f.__memo__ = {}
    
    @wraps(f)
    def g(*args):
        if args not in f.__memo__:
            f.__memo__[args] = f(*args)
        
        return f.__memo__[args]
    
    return g
